//
//  JJUrlConfigManager.swift
//  swiftStudy
//
//  Created by hamilyjing on 2020/6/26.
//  Copyright © 2020 JJ. All rights reserved.
//

import Foundation

class JJUrlConfigManager {
    var urlConfigDic = [String: Any]()
    var environmentName = "Product"
    
    static let shared = JJUrlConfigManager()
    
    private init() {
        let filePath = Bundle.main.path(forResource: "JJUrlConfig", ofType: "json")
        var data: Data?
        do {
            data = try Data(contentsOf: URL(fileURLWithPath: filePath!))
        } catch let error as NSError {
            assert(false, error.description)
        }
        
        let config = data!.jjs_dictionary() as! [String: Any]
        addUrlConfig(config)
    }
    
    func addUrlConfig(_ config: [String: Any]) -> Void {
        if config["Base"] != nil {
            _addUrlConfig(config["Base"] as! [String: Any])
        }
        
        if config["Environment"] != nil {
            _addUrlConfig(config["Environment"] as! [String: Any])
        }
    }
    
    private func _addUrlConfig(_ config_: [String: Any]) -> Void {
        if (urlConfigDic.count == 0) {
            urlConfigDic = dictionaryMerge(dic1: urlConfigDic, dic2: config_) as! [String : Any]
            return
        }
        
        for (key, value) in config_ {
            if urlConfigDic[key] != nil {
                var dic = urlConfigDic[key] as! [String: Any]
                dic = dictionaryMerge(dic1: dic, dic2: value as! [AnyHashable : Any]) as! [String : Any]
                urlConfigDic[key] = dic
            } else {
                urlConfigDic[key] = value
            }
        }
    }
    
    func serverUrl(_ identity_: String) -> String {
        var urlString = serverHost(identity_)
        urlString += serverPath(identity_)
        return urlString
    }
    
    func serverHost(_ identity_: String) -> String {
        let hostKey = "SERVER_HOST_URL"
        
        var envDic = urlConfigDic[environmentName] as? [String: [String: Any]]
        var identityDic = envDic?[identity_]
        var host = identityDic?[hostKey]
        if host != nil {
            return host as! String
        }
        
        identityDic = urlConfigDic[identity_] as? [String: [String: Any]]
        let configDicIdentity = identityDic?["SERVER_HOST_Environment_Config_Identity"] as? String
        if configDicIdentity != nil {
            var configDic = urlConfigDic[configDicIdentity!] as? [String: [String: Any]]
            var tempEnvDic = configDic?[environmentName]
            host = tempEnvDic?[hostKey]
            if host != nil {
                return host as! String
            }
        }
        
        identityDic = urlConfigDic[identity_] as? [String: [String: Any]]
        host = identityDic?[hostKey]
        if host != nil {
            return host as! String
        }
        
        var tempEnvDic = urlConfigDic[environmentName] as? [String: Any]
        host = tempEnvDic?[hostKey]
        return host as! String
    }
    
    func serverPath(_ identity_: String) -> String {
        let pathKey = "SERVER_PATH_URL"
        
        var envDic = urlConfigDic[environmentName] as? [String: [String: Any]]
        var identityDic = envDic?[identity_]
        var path = identityDic?[pathKey]
        if path != nil {
            return path as! String
        }
        
        var tempIdentityDic = urlConfigDic[identity_] as? [String: Any]
        path = tempIdentityDic?[pathKey]
        return path as! String
    }
    
    func existForIdentity(_ identity_: String) -> Bool {
        let exist = (urlConfigDic[identity_] != nil)
        return exist
    }
    
    func getValue(_ identity_: String) -> Any? {
        return getValue(identity_, key: nil)
    }
    
    func getValue(_ identity_: String, key key_: String?) -> Any? {
        var envDic = urlConfigDic[environmentName] as? [String: Any]
        var value = envDic?[identity_]
        if value != nil {
            return value
        }
        
        if key_ == nil {
            value = urlConfigDic[identity_]
        } else {
            var identityDic = urlConfigDic[identity_] as? [String: Any]
            value = identityDic?[key_!]
        }
        
        return value
    }
    
    func dictionaryMerge(dic1: [AnyHashable: Any], dic2: [AnyHashable: Any]) -> [AnyHashable: Any] {
        var newDic = dic1
        for (key, value) in dic2 {
            newDic[key] = value
        }
        return newDic
    }
}
